<template>
  <div class="m-upload">
    <div
      v-for="(img, id) of value"
      :key="id"
      class="m-upload-item"
      :style="{ width: `${width}px`, height: `${height}px` }"
    >
      <van-image
        :width="width"
        :height="height"
        fit="cover"
        :src="img.url"
        @click="preview(id)"
      />
      <span v-if="img.name" class="item-name">{{ img.name }}</span>
      <span class="item-close" @click="del(id)">
        <van-icon name="cross" />
      </span>
    </div>
    <template v-if="!len || (multiple && len < max)">
      <empty
        :width="width"
        :accept="accept"
        :bus-type="busType"
        :multiple="multiple"
        :len-max="lenMax"
        :max-size="maxSize"
        :height="height"
        :bg-image="bgImage"
        :upload-text="uploadText"
        @upload="$emit('after-upload', $event)"
      >
        <template #icon>
          <slot v-if="$slots.icon" name="icon"></slot>
          <template v-else>
            <van-icon name="photograph" class="m-default-icon" />
            <span>{{ uploadText }}</span>
          </template>
        </template>
      </empty>
    </template>
    <!-- 预览 -->
    <van-image-preview
      v-model="show"
      :start-position="current"
      :images="images"
      closeable
    />
  </div>
</template>
<script>
import { ImagePreview } from 'vant'
import Empty from './empty.vue'
import { deepCopy } from '@/utils/'
import { isArray } from '@/utils/api'
export default {
  name: 'MUpload',
  components: {
    Empty,
    [ImagePreview.Component.name]: ImagePreview.Component,
  },
  props: {
    value: {
      type: Array,
      default: () => [],
    },
    multiple: {
      type: Boolean,
    },
    accept: {
      type: String,
      default: 'image/*',
    },
    maxSize: {
      type: Number,
      default: 10485760,
    },
    width: {
      type: [Number, String],
      default: 82,
    },
    height: {
      type: [Number, String],
      default: 82,
    },
    uploadText: {
      type: String,
      default: '',
    },
    bgImage: {
      type: String,
      default: '',
    },
    max: {
      type: Number,
      default: 12,
    },
    busType: {
      type: Number,
      default: 6,
    },
    alt: {
      type: String,
      default: '',
    },
  },
  data() {
    return {
      show: null,
      current: 0,
    }
  },
  computed: {
    images() {
      let imgs = []
      if (isArray(this.value)) imgs = this.value.map((ret) => ret.url)
      return imgs
    },
    len() {
      return isArray(this.value) && this.value.length
    },
    lenMax() {
      return this.max - this.len
    },
  },
  methods: {
    del(id) {
      const deepValues = deepCopy(this.value)
      deepValues.splice(id, 1)
      this.$emit('input', deepValues)
    },
    preview(index) {
      this.current = index
      this.show = true
    },
  },
}
</script>
<style lang="less" scoped>
@item-radius: 5px;
.m-upload {
  font-size: 0;
  display: inline;
  &-item,
  &-empty {
    position: relative;
    display: inline-block;
    vertical-align: top;
    margin-top: 8px;
    overflow: hidden;
  }
  &-item {
    margin-right: 6px;
    .item-close,
    .item-name {
      position: absolute;
      z-index: 3;
      color: #efefef;
      display: inline-flex;
      justify-content: center;
      align-items: center;
    }
    .item-name {
      width: inherit;
      height: 26px;
      font-size: 12px;
      bottom: 0;
      left: 0;
      right: 0;
      background-image: linear-gradient(
        0deg,
        rgba(50, 50, 50, 0.52),
        rgba(50, 50, 50, 0.24),
        rgba(50, 50, 50, 0)
      );
    }
    .item-close {
      width: 18px;
      height: 18px;
      border-radius: 18px;
      background-color: rgba(0, 0, 0, 0.24);
      right: 4px;
      top: 4px;
      font-size: 12px;
    }
  }
  &-empty {
    position: relative;
    z-index: 3;
    border: dashed 1px #ddd;
    border-radius: @item-radius;
    background-color: #fafafa;
    :deep(input) {
      width: inherit;
      height: inherit;
      position: absolute;
      z-index: 3;
      top: 0;
      opacity: 0;
    }
  }
  :deep(img) {
    border-radius: @item-radius;
  }
}
</style>
